<template>
  <div class="transfer">
    <div class="panel">
      <div class="title">
        待选区
      </div>
      <div class="tree">
        <el-input class="search" v-model="filterText1" placeholder="" :prefix-icon="Search"/>
        <el-checkbox v-if="types==1&&!isDisabled" v-model="isSelectAll" :indeterminate="isIndeterminate"
                     @change="handleCheckAllChange" label="全选" style="position: relative;left: 24px"/>
        <el-tree style="max-height: 400px;overflow: auto;" ref="treeRef1" :data="dataSource1" show-checkbox
                 node-key="id"
                 default-expand-all :expand-on-click-node="false"
                 :check-strictly="true"
                 :props="defaultProps"
                 :filter-node-method="filterNode1"
                 @check="handleCheck1"/>
      </div>
    </div>
    <div class="btn">
      <el-button @click="handleChange221" :disabled="isShowLeftData" type="primary" icon="ArrowLeftBold"/>
      <el-button @click="handleChange122" :disabled="isShowRightData" type="primary" icon="ArrowRightBold"/>
    </div>
    <div class="panel">
      <div class="title">
        已选区
      </div>
      <div class="tree">
        <el-input class="search" v-model="filterText2" placeholder="" :prefix-icon="Search"/>
        <el-checkbox v-if="types==1&&dataSource2.length!=0" v-model="isSelectLeftAll"
                     :indeterminate="isLeftIndeterminate"
                     @change="handleCheckAllLeftChange" label="全选" style="position: relative;left: 24px"/>
        <el-tree style="max-height: 400px;overflow: auto;" ref="treeRef2" :data="dataSource2" show-checkbox
                 node-key="id"
                 default-expand-all :expand-on-click-node="false"
                 :check-strictly="true" :props="defaultPropsLeft"
                 :filter-node-method="filterNode2"
                 @check="handleCheck2"/>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { ref, onMounted, reactive, defineProps, defineEmits, watch, nextTick, toRaw, computed } from 'vue'
import { Search } from '@element-plus/icons-vue'
import { ElTree } from 'element-plus'
import * as Console from 'console'

interface Tree {
  [key: string]: any
}

const emits = defineEmits(['change'])

const props = defineProps({
  value: {
    type: Array,
    default: () => [],
  },
  data: {
    type: Array,
    default: () => [],
  },
  types: {
    type: Number,
    default: () => 1,
  },
  isShow: {
    type: Boolean,
    default: false
  },
  classType: {
    type: null,
    default: null
  }

})

const defaultProps = {
  children: 'children',
  label: 'label',
  disabled: 'isDisabled',
}
const defaultPropsLeft = {
  children: 'children',
  label: 'label',
}

const filterText1 = ref('')
const filterText2 = ref('')
const treeRef1 = ref<InstanceType<typeof ElTree>>()
const treeRef2 = ref<InstanceType<typeof ElTree>>()

const dataSource1 = ref([] as any)
const dataSource2 = ref([] as any)
const typesNum = ref([] as any)

const checkedTreeKeysLeft = ref([])
const checkedTreeKeysRight = ref([])
const isSelectAll = ref(false)
const isIndeterminate = ref(false)
const isDisabled = ref(false)

const isShowLeftData = ref(true)
const isShowRightData = ref(true)

//是否全选
const handleCheckAllChange = (val: boolean) => {
  let arr: any = []
  if (val) {
    dataSource1.value.forEach((item: any) => {
      arr.push(item.staffId)
    })
  }
  checkedTreeKeysLeft.value = arr
  treeRef1.value!.setCheckedKeys(arr, false)
  isIndeterminate.value = false
  if (checkedTreeKeysLeft.value.length != 0) {
    isShowRightData.value = false
  } else {
    isShowRightData.value = true
  }
}

const isSelectLeftAll = ref(false)
const isLeftIndeterminate = ref(false)
//是否全选
const handleCheckAllLeftChange = (val: boolean) => {
  let arr: any = []
  if (val) {
    dataSource2.value.forEach((item: any) => {
      arr.push(item.staffId)
    })
  }
  checkedTreeKeysRight.value = arr
  treeRef2.value!.setCheckedKeys(arr, false)
  isLeftIndeterminate.value = false
  if (checkedTreeKeysRight.value.length != 0) {
    isShowLeftData.value = false
  } else {
    isShowLeftData.value = true
  }
}

//展开树状图
const filterTreeArray = (array: any) => {
  let newData: any[] = []
  const callback = (item: any) => {
    (item.children || (item.children = [])).map((v: any) => {
      callback(v)
    })
    delete item.children
    newData.push(item)
  }
  array.map((v: any) => callback(v))
  return newData
}
//递归查询数据
const deepFn = (arr = [], numArr = [], isDisabled: boolean) => {
  arr.forEach((item: any) => {
    if (item.children&&item.children.length>0) {
      item.isDisabled=true
      deepFn(item.children, numArr, isDisabled)
    }
    numArr.forEach((resp: any) => {
      if (item.id === resp) {
        item.isDisabled = isDisabled
      }
    })
  })
  return arr
}
//右转左
const handleCheck1 = (checkedNodes: any, {
  checkedKeys,
}: any) => {
  checkedTreeKeysLeft.value = checkedKeys
  isIndeterminate.value = checkedKeys.length > 0 && checkedKeys.length < dataSource1.value.length
  if (checkedKeys.length != 0) {
    isShowRightData.value = false
  } else {
    isShowRightData.value = true
  }
}
const handleCheck2 = (checkedNodes: any, {
  checkedKeys,
}: any) => {
  checkedTreeKeysRight.value = checkedKeys
  isLeftIndeterminate.value = checkedKeys.length > 0 && checkedKeys.length < dataSource2.value.length
  if (checkedKeys.length != 0) {
    isShowLeftData.value = false
  } else {
    isShowLeftData.value = true
  }
}
// 左砖右
const handleChange122 = () => {
  let filterLeft = null
  let filterRightData = null

  if (typesNum.value !== 1) {
    //将左边的树展开
    filterLeft = filterTreeArray(JSON.parse(JSON.stringify(dataSource1.value)))
    //去掉已选择的内容
    filterRightData = filterLeft.filter((item: any) => checkedTreeKeysLeft.value.some(item2 => item2 === item.id))
  } else {
    //去掉已选择的内容
    filterRightData = dataSource1.value.filter((item: any) => checkedTreeKeysLeft.value.some(item2 => item2 === item.id))
  }

  dataSource2.value =dataSource2.value.concat(filterRightData);
  dataSource2.value=newArrFn(dataSource2.value)

  dataSource1.value = deepFn(dataSource1.value, checkedTreeKeysLeft.value, true)
  checkedTreeKeysLeft.value=[]
  isShowRightData.value = true
  treeRef1.value!.setCheckedKeys([], false)
}
// 右转左
const handleChange221 = () => {
  //去掉已选择的内容
  const filterRightData = dataSource2.value.filter((item: any) => !checkedTreeKeysRight.value.some(item2 => item2 === item.id))
  dataSource2.value = filterRightData

    dataSource1.value = deepFn(dataSource1.value, checkedTreeKeysLeft.value, true)

   // dataSource1.value = arrs.concat(dataSource1.value)
    dataSource2.value = dataSource2.value.filter((item) => !checkedTreeKeysRight.value.includes(item.id));
  dataSource1.value=deepFn(dataSource1.value,checkedTreeKeysRight.value,false)
  if (checkedTreeKeysRight.value.length === 0) {
    isDisabled.value = true
  } else {
    isDisabled.value = false
  }
  checkedTreeKeysRight.value=[]
  isShowLeftData.value = true

}
const newArrFn =(arr) =>{
  const res = new Map();
  return arr.filter(arr => !res.has(arr.id) && res.set(arr.id, arr.id));
}
const filterNode1 = (value: string, data: Tree) => {
  if (!value) return true
  return data.label.includes(value)
}

const filterNode2 = (value: string, data: Tree) => {
  if (!value) return true
  return data.label.includes(value)
}
onMounted(()=>{
  const ids: any[] | undefined=[]
  props.value?.forEach(item=>{
    ids.push(item.id)
  })
  let moreData = deepFn(JSON.parse(JSON.stringify(props.data as any)), ids, true)
  dataSource1.value = moreData
  dataSource2.value = props.value
})
watch(() => [props.isShow, props.classType], (newValue, oldValue) => {
    if(props.isShow){
      const ids: any[] | undefined=[]
      props.value?.forEach(item=>{
        ids.push(item.id)
      })
      let moreData = deepFn(JSON.parse(JSON.stringify(props.data as any)), ids, true)
      dataSource1.value = moreData
      dataSource2.value = props.value
    }

})

watch(dataSource2, (val) => {
  emits('change', val)
})
watch(filterText1, (val) => {
  treeRef1.value!.filter(val)
})
watch(filterText2, (val) => {
  treeRef2.value!.filter(val)
})
</script>

<style lang="less" scoped>
.transfer {
  display: flex;
  align-items: stretch;
  justify-content: center;

  .panel {
    flex-grow: 1;
    border: 0.0625rem solid #ebeef5;
    border-radius: 0.25rem;

    .title {
      font-size: 1rem;
      color: #303133;
      font-weight: 400;
      border-bottom: 1px solid #ebeef5;
      height: 40px;
      line-height: 40px;
      background-color: #f5f7fa;
      padding-left: 16px;
      position: relative;

      .ps1 {
        position: absolute;
        right: 0.9375rem;
        top: 50%;
        transform: translate3d(0, -50%, 0);
        color: #909399;
        font-size: 0.75rem;
        font-weight: 400;
      }
    }

    .tree {
      min-height: 300px;
    }
  }

  .btn {
    width: 162px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .tree {
    .search {
      margin: 15px 10px;
      width: calc(100% - 20px);
    }
  }
}
</style>
